﻿/********************************/
/****** TCP Socket FOR WIN  *****/
/********************************/
//SOCKET.h

#ifndef _SOCKET_
#define _SOCKET_

#include <windows.h>
#include "stdio.h"
#include <sys/types.h>
#include <time.h>
#include "string.h"
#include "signal.h"

#define SIZE	(512*1024)   //buffer size
//#define SIZE	(24*1024)   //buffer size

class CSocket;

class CSock
{
public:
	
	CSock(int socket,CSocket* pSocket);
	~CSock();
	
	int Send(char* buffer,int len);         //data send function for CSock
	int Recv(char* buffer,int len);         //data receive function for CSock
	int CheckValidData();                //check validity of the received data to ignore watch data
	
	static DWORD WINAPI SendThread(void* arg);    //data send thread for CSock
	static DWORD WINAPI RecvThread(void* arg);    //data receive thread for CSock
	static DWORD WINAPI WatchThread(void* arg);   //watch thread for CSock 
		
	unsigned char*	m_sendBuffer;        //send buffer
	unsigned char*	m_recvBuffer;        //receive buffer 
	int			m_sendStart;             //start position for sending 
	int			m_sendEnd;               //end position for sending
	int			m_recvStart;             //start position for receiving
	int			m_recvEnd;               //end position for receiving 
	
	int			m_socket;          //sock for this CSock object
	CSocket*	m_pParent;         //parent CSocket object of this CSock object 
	int         m_watchFlag;        //flag for wacthing in order to check whether connection is keep 

	HANDLE 		m_watchThread;        //handle of watch thread
	HANDLE 		m_sendThread;        //handle of send thread
	HANDLE 		m_recvThread;       //handle of receive thread

	CRITICAL_SECTION 		m_cs;         //semaphore
	HANDLE					m_event1;     //handle of event1
	HANDLE					m_event2;     //handle of event2
	int m_nCount;
};

class CSocket
{
	friend CSock;
	
	public:
		CSocket(int port, bool bServer);
		~CSocket();
		
		// server function                      //for server to listen
		bool Listen(int maxConnectCount);       //listen thread function
		static DWORD WINAPI ListenThread(void* arg);

		// client function
		bool Connect(char ipAddr[],int port);    //for client to connect server

		//public function
		int GetValidLineCount();                                //get count of connected CSock
		CSock* GetLineByIndex(int nIndex);                      //get CSock object by index from CSock array  
		int SendData(CSock* pSocket,char* buffer,int len);      //for CSocket to send data
		int RecvData(CSock* pSocket,char* buffer,int len);      //for CSocket to receive data 
		int SetCallBack(void (*proc)(CSock* pSocket,int MSG));  //set callback function

		void OnRecv(CSock* pSocket);                  //for calling callback function
		void EndSocket(CSock* pSocket);               //delete a CSock object from sock array
		void SetMsg(int msg);                         //set message to m_msg
		
	private:				
		void (*m_pRecvCallBack)(CSock* pSocket,int MSG);
		bool		m_bServer;          //flag for server
		CSock*	    m_pSocket[16];      //CSock array
		volatile int			m_lineCount;        //count of connected CSock 
		
		int			m_port;              //local port
		int			m_maxConnectCount;   //max count of CSock can be connected
		HANDLE		m_listenThread;		 //handle for listen thread
		int			m_listenSocket;      //sock for listening
	public:
		int			m_msg;              //message from callback function
		CRITICAL_SECTION 		m_cs;   //semaphore
};

#endif